package com.yyx.lgb.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.yyx.lgb.cart.service.CartService;
import com.yyx.lgb.feign.product.ProductFeignClient;
import com.yyx.lgb.model.entity.h5.CartInfo;
import com.yyx.lgb.model.entity.product.ProductSku;
import com.yyx.lgb.utils.AuthContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: cartServiceImpl
 * Package: com.yyx.lgb.cart.service.impl
 * Description:
 *
 * @Author: yyx
 * @Create: 2025/8/12 - 16:56
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private ProductFeignClient productFeignClient;
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //必须是登录状态
        Long userId = AuthContextUtil.getUserInfo().getId();
        //构建key的名称
        String cartKey=this.getCartKey(userId);
        //2因为购物车放到redis里面
        //  从redis里面获取购物车数据，根据用户id + skuId获取 (hash类型key + field)
        //  hash类型  key : userId  field: skuId   value: sku  信息cartInfo
        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));

        //3如果购物车存在添加商品，把商品数量相加
        CartInfo cartInfo = null ;
        if(cartInfoObj != null) {       //  如果购物车中有该商品，则商品数量 相加！
            cartInfo = JSON.parseObject(cartInfoObj.toString() , CartInfo.class) ;
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        }else {
            //4如果购物车没有添加商品，直接商品添加购物车（添加到redis里面)
            //远程调用实现:通过nacos + openFeign实现根据skuId获取商品sku信息
            cartInfo = new CartInfo();
            // 远程调用实现:根据skuId获取商品sku信息
            ProductSku productSku = productFeignClient.getBySkuId(skuId);

            //设置相关数据到cartInfo对象里面
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setImgUrl(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());
        }
        //添加到redis里面
        // 将商品数据存储到购物车中
        redisTemplate.opsForHash().put(cartKey , String.valueOf(skuId) , JSON.toJSONString(cartInfo));
    }

    private String getCartKey(Long userId) {
        return "user:cart"+userId;
    }

    @Override
    public List<CartInfo> getCartList() {
        //1构建查询的redis里面key值，根据当前userId
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(userId);

        //2根据key 从redis里面hash类型获取所有value值 cartInfo
        List<Object> cartInfoList = redisTemplate.opsForHash().values(cartKey);

        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<CartInfo> infoList = cartInfoList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return infoList ;
        }

        // []
        return new ArrayList<>() ;
    }

    @Override
    public void deleteCart(Long skuId) {

        // 获取当前登录的用户数据
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //获取缓存对象
        redisTemplate.opsForHash().delete(cartKey  ,String.valueOf(skuId)) ;
    }

    //业务接口实现
    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1构建查询的redis里面key值，根据当前userId
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = this.getCartKey(userId);

        //2判断key是否包含fiLed
        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));

        if(hasKey) {
            //3根据key + field把value获取出来
            String cartInfoJSON = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId)).toString();
            CartInfo cartInfo = JSON.parseObject(cartInfoJSON, CartInfo.class);
            //4更新value里面选中状态
            cartInfo.setIsChecked(isChecked);
            //5放回到redis的hash类型里面
            redisTemplate.opsForHash().put(cartKey , String.valueOf(skuId) , JSON.toJSONString(cartInfo));
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {

        //1构建查询的redis里面key值，根据当前userId
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //2根据key获取购物车所有value值
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);


        //判断不为空
        if(!CollectionUtils.isEmpty(objectList)) {
            List<CartInfo> cartInfoList = objectList.stream().map(object ->
                    JSON.parseObject(object.toString(), CartInfo.class)).collect(Collectors.toList());


            //3把每个商品isChecked进行更新
            cartInfoList.forEach(cartInfo -> {
                cartInfo.setIsChecked(isChecked);
                redisTemplate.opsForHash().put(cartKey,String.valueOf(cartInfo.getSkuId()),
                        JSON.toJSONString(cartInfo));

            });

        }
    }

    @Override
    public void clearCart() {
        //1构建查询的redis里面key值，根据当前userId
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);
        //2根据key删除redis里面数据
        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getAllCkecked() {
        //获取userid，构建key
        Long userId = AuthContextUtil.getUserInfo().getId();
        String cartKey = getCartKey(userId);

        //根据key获取购物车所有商品
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);
        if(!CollectionUtils.isEmpty(objectList)) {
            List<CartInfo> cartInfoList = objectList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)//选中
                    .collect(Collectors.toList());
            return cartInfoList ;
        }
        return new ArrayList<>() ;
    }

}
